using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using RollManager.Library.Utils;

namespace RollManager.Library.ActionSteps
{
    [Serializable]
    public class RestoreFilesStep : ActionStep
    {
        private string m_srcDir = StepConstants.PATH;
        private string m_destDir = StepConstants.PATH;
        private string m_prefix = "Target";
        private bool m_removeBackup = true;

        [DisplayName( "Destination Dir" )]
        [Description( "The destination directory path to which files are restored." )]
        public string DestDir
        {
            get
            {
                return m_destDir;
            }
            set
            {
                if( string.IsNullOrEmpty( value ) )
                {
                    throw new ArgumentException( "Destination Dir cannot be empty." );
                }
                else
                {
                    m_destDir = value.Trim();
                }
            }
        }

        [Description( "The prefix for the backup folder name that was created in the destination dir." )]
        public string Prefix
        {
            get
            {
                return m_prefix;
            }
            set
            {
                if( string.IsNullOrEmpty( value ) )
                {
                    throw new ArgumentException( "Prefix cannot be empty." );
                }
                else
                {
                    m_prefix = value.Trim();
                }
            }
        }

        [Description( "Whether the backup folder should be deleted after the restore is complete." )]
        public bool RemoveBackup
        {
            get
            {
                return m_removeBackup;
            }
            set
            {
                m_removeBackup = value;
            }
        }

        [DisplayName( "Source Dir" )]
        [Description( "The source directory path from where files were backed up." )]
        public string SrcDir
        {
            get
            {
                return m_srcDir;
            }
            set
            {
                if( string.IsNullOrEmpty( value ) )
                {
                    throw new ArgumentException( "Source Dir cannot be empty." );
                }
                else
                {
                    m_srcDir = value.Trim();
                }
            }
        }

        public override string Name
        {
            get { return "Restore Files"; }
        }

        protected override void Run()
        {
            fixSourceDir();

            DirectoryHelper helper = new DirectoryHelper( Progress );

            Progress.AddFormat( "***** Remove current code in {0} on {1} *****", m_destDir, CurrentServer );
            helper.Delete( m_destDir, true );

            // Get backup folder
            string lastBackupFolder = getBackupFolder();

            Progress.AddFormat( "***** Rollback {0} on {1} *****", m_destDir, CurrentServer );
            helper.Copy( lastBackupFolder, m_destDir, true );

            if( LastServer && m_removeBackup )
            {
                Progress.AddFormat( "***** Remove backup directory {0} *****", m_destDir, CurrentServer );
                helper.Delete( lastBackupFolder, true );
            }
        }

        private void fixSourceDir()
        {
            m_srcDir = m_srcDir.Replace( CurrentServer, FirstServer );
        }

        private string getBackupFolder()
        {
            List<DirectoryInfo> dirs =
                Common.ListDirectories( m_srcDir, string.Format( "{0}*", m_prefix ), SearchOption.TopDirectoryOnly );

            if( dirs.Count < 1 )
            {
                throw new Exception( string.Format( "No backup folders found for {0} on {1}", m_prefix, m_srcDir ) );
            }

            return Path.Combine( m_srcDir, dirs[ 0 ].Name );
        }

        protected override void Simulate()
        {
            fixSourceDir();

            // Check for dest dir
            DirectoryInfo dir = new DirectoryInfo( m_destDir );
            if( !dir.Exists )
            {
                throw new Exception( 
                    string.Format( "Destination dir {0} does not exist on {1}.", m_destDir, CurrentServer ) );
            }

            Progress.AddFormat( "Simulated delete of files in {0} on {1}", m_destDir, CurrentServer );


            // Check for source dir
            dir = new DirectoryInfo( m_srcDir );
            if( !dir.Exists )
            {
                throw new Exception(
                    string.Format( "Source dir {0} does not exist.", m_srcDir ) );
            }

            string backupFolder = getBackupFolder();
            dir = new DirectoryInfo( backupFolder );
            if( !dir.Exists )
            {
                throw new Exception(
                    string.Format( "Backup dir {0} does not exist.", backupFolder ) );
            }

            Progress.AddFormat( "Simulated copy from {0} to {1}", backupFolder, m_destDir );

            if( LastServer )
            {
                Progress.AddFormat( "Simulated delete of folder {0}", backupFolder );
            }
        }
    }
}
